﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.Threading;
using CalendarWeekRule = CLFramework.Globalization.CalendarWeekRule;

namespace CLFramework
{
    /// <summary>
    /// A class contains some global settings. 
    /// The value of settings is load from asb.mes/settings section in application config file.
    /// </summary>
    public static class GlobalSettings
    {
        #region Members

        public const string SettingSectionName = "asb.mes/settings";

        //Default language
        private static string defaultLanguage = "en-US";
        //First day of one week
        private static DayOfWeek firstDayOfWeek;
        //The rule of First week of one year
        private static CalendarWeekRule firstWeekOfYear;

        //If is in a web application
        private static bool isWebApplication;
        private static IDictionary<string, string> supportedLanguages;
        //System version
        private static string systemVersion = "1.0";

        private static string defaultLoggingPolicyName = "DefaultPolicy";

        private static string defaultConnectionName = "dev";

        private static string businessExceptionPolicy = "DefaultPolicy";

        private static string dataAccessExceptionPolicy = "DefaultPolicy";

        private static string presentationExceptionPolicy = "DefaultPolicy";

        #endregion

        /// <summary>
        /// Initializes the <see cref="GlobalSettings"/> class.
        /// </summary>
        static GlobalSettings()
        {
            LoadSettings();
        }

        #region LoadSettings

        /// <summary>
        /// Loads the settings from application config file.
        /// </summary>
        private static void LoadSettings()
        {
            //todo logging
            // todo using configuration block ASB.MES.Framework.Configuration.ConfigurationService.GetApplicationKeyValueSetting
            //Debug.WriteLine(ConfigurationService.GetApplicationKeyValueSetting("MESFramework.LogInfo", "global", "test"));
            Debug.WriteLine("Begin load global settings from " + SettingSectionName);
            //Get setting list with type ISettingList from application config section
            //ISettingList settings = ConfigurationManager.GetSection(SettingSectionName) as ISettingList;
            //if (settings != null)
            //{
            //    ISectionSettingFactory settingFactory = new SectionSettingFactory(settings);
            //    supportedLanguages =
            //        settingFactory.GetSectionSettingValue<IDictionary<string, string>>("SupportedLanguages");
            //    defaultLanguage = settingFactory.GetSectionSettingValue<string>("DefaultLanguage");
            //    isWebApplication = settingFactory.GetSectionSettingValue<bool>("IsWebApplication");
            //    firstDayOfWeek = settingFactory.GetSectionSettingValue<DayOfWeek>("FirstDayOfWeek");
            //    firstWeekOfYear = settingFactory.GetSectionSettingValue<CalendarWeekRule>("FirstWeekOfYear");
            //    systemVersion = settingFactory.GetSectionSettingValue<string>("SystemVersion") ?? systemVersion;
            //    defaultLoggingPolicyName = settingFactory.GetSectionSettingValue<string>("DefaultLoggingPolicyName") ?? defaultLoggingPolicyName;
            //    defaultConnectionName = settingFactory.GetSectionSettingValue<string>("DefaultConnectionName") ?? defaultConnectionName;
            //    businessExceptionPolicy = settingFactory.GetSectionSettingValue<string>("BusinessExceptionPolicy") ?? businessExceptionPolicy;
            //    dataAccessExceptionPolicy = settingFactory.GetSectionSettingValue<string>("DataAccessExceptionPolicy") ?? dataAccessExceptionPolicy;
            //    presentationExceptionPolicy = settingFactory.GetSectionSettingValue<string>("PresentationExceptionPolicy") ?? presentationExceptionPolicy;
            //}
            //else
            //{
            //    Debug.WriteLine("No any settings can be found in application config file");
            //}

            //Debug.WriteLine("Load global settings end");
        }

        #endregion

        #region Property

        #region IsWebApplication

        /// <summary>
        /// Gets a value indicating whether this instance is web application.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is web application; otherwise, <c>false</c>.
        /// </value>
        public static bool IsWebApplication
        {
            [DebuggerStepThrough]
            get { return isWebApplication; }
        }

        #endregion

        #region DefaultLanguage

        /// <summary>
        /// Gets or sets the default language.
        /// </summary>
        /// <value>The default language.</value>
        /// <remarks>This property specited error message , ui element 's language</remarks>
        public static string DefaultLanguage
        {
            [DebuggerStepThrough]
            get { return defaultLanguage; }
            [DebuggerStepThrough]
            set
            {
                defaultLanguage = value;
                Thread.CurrentThread.CurrentUICulture = new CultureInfo(defaultLanguage);
            }
        }

        #endregion

        #region SupportedLanguages

        /// <summary>
        /// Gets the supported languages.
        /// </summary>
        /// <value>The supported languages.</value>
        public static IDictionary<string, string> SupportedLanguages
        {
            [DebuggerStepThrough]
            get { return supportedLanguages; }
        }

        #endregion

        #region CurrentLanguage

        /// <summary>
        /// Gets the current language. 
        /// When got current language, Thread.CurrentThread.CurrentUICulture 
        /// will be set same with current culture.
        /// </summary>
        /// <value>The current language.</value>
        public static string CurrentLanguage
        {
            get
            {
                //User user = Users.Current;
                //string language = (user != null) ? user.Language : DefaultLanguage;
                string language = DefaultLanguage;

                if (Thread.CurrentThread.CurrentUICulture.Name != language)
                {
                    Thread.CurrentThread.CurrentUICulture = new CultureInfo(language);
                }

                return language;
            }
        }

        #endregion

        #region CurrentCulture

        /// <summary>
        /// Gets the current culture info.
        /// </summary>
        /// <value>The current culture.</value>
        public static CultureInfo CurrentCulture
        {
            get { return new CultureInfo(CurrentLanguage); }
        }

        #endregion

        #region FirstDayOfWeek

        /// <summary>
        /// Gets or sets the first day of week.
        /// </summary>
        /// <value>The first day of week.</value>
        public static DayOfWeek FirstDayOfWeek
        {
            [DebuggerStepThrough]
            get { return firstDayOfWeek; }
            [DebuggerStepThrough]
            set { firstDayOfWeek = value; }
        }

        #endregion

        #region FirstWeekOfYear

        /// <summary>
        /// 取得或设定年份第一周的不同规则。<br />
        /// <list type="table">
        ///     <listheader>
        ///         <term>成员名称</term>
        ///         <description>说明</description>
        ///     </listheader>
        ///     <item>
        ///         <term>FirstDay</term>
        ///         <description>指示年的第一周从该年的第一天开始，到所指定周的下一个首日前结束。</description>
        ///     </item>
        ///     <item>
        ///         <term>FirstFourDayWeek</term>
        ///         <description>指示年的第一周是第一个在指定的周首日前包含四天或更多天(最多七天)的周。符合 ISO 8601。第一个至少包含新年中四天的星期。</description>
        ///     </item>
        ///     <item>
        ///         <term>FirstFullWeek</term>
        ///         <description>指示年的第一周从所指定周首日的第一个匹配项开始，可以是年的第一天或其后某一天。一年中第一个完整的星期。</description>
        ///     </item>
        ///     <item>
        ///         <term>FirstDayAndMore</term>
        ///         <description>指示年的第一周从该年的第一天所在周的第一天(可能为上年)开始，其中上年的几天同时存在于上年最后一周。</description>
        ///     </item>
        /// </list>
        /// </summary>
        /// <value>The first week of year.</value>
        public static CalendarWeekRule FirstWeekOfYear
        {
            [DebuggerStepThrough]
            get { return firstWeekOfYear; }
            [DebuggerStepThrough]
            set { firstWeekOfYear = value; }
        }

        #endregion

        #region SystemVersion

        /// <summary>
        /// Gets the system version. In general, this setting will be set by setup application.
        /// </summary>
        /// <value>The system version.</value>
        public static string SystemVersion
        {
            [DebuggerStepThrough]
            get { return systemVersion; }
        }

        #endregion

        /// <summary>
        /// Gets the default name of the logging policy.
        /// </summary>
        /// <value>The default name of the logging policy.</value>
        public static string DefaultLoggingPolicyName
        {
            get { return defaultLoggingPolicyName; }
        }

        /// <summary>
        /// Gets the default name of the connection.
        /// </summary>
        /// <value>The default name of the connection.</value>
        public static string DefaultConnectionName
        {
            get { return defaultConnectionName; }
        }

        /// <summary>
        /// Gets the business exception policy.
        /// </summary>
        /// <value>The business exception policy.</value>
        public static string BusinessExceptionPolicy
        {
            get { return businessExceptionPolicy; }
        }

        /// <summary>
        /// Gets the data access exception policy.
        /// </summary>
        /// <value>The data access exception policy.</value>
        public static string DataAccessExceptionPolicy
        {
            get { return dataAccessExceptionPolicy; }
        }

        /// <summary>
        /// Gets the presentation exception policy.
        /// </summary>
        /// <value>The presentation exception policy.</value>
        public static string PresentationExceptionPolicy
        {
            get { return presentationExceptionPolicy; }
        }


        #endregion
    }
}
